package com.bottle.android_mvvm.ui.view

import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.bottle.android_mvvm.domain.ext.getVmClazz
import com.bottle.android_mvvm.domain.viewmodel.BaseMVVMViewModel
import com.bottle.lib_core.ui.view.BaseBingFragment

/**
 * BaseMVVMFragment 是一个基于 MVVM 架构的 Fragment 基类，封装了 ViewModel 的初始化、UI 事件注册以及数据观察者的创建。
 * 它继承自 [BaseBingMVVMFragment]，并引入了泛型参数以支持灵活的 ViewModel 和 ViewBinding 配置。
 *
 * ### 泛型参数
 * - [VM]: 表示使用的 ViewModel 类型，必须继承自 [BaseMVVMViewModel]。
 * - [VB]: 表示使用的 ViewBinding 类型，必须继承自 [ViewBinding]。
 *
 * ### 核心功能
 * 1. **ViewModel 初始化**:
 *    - 提供了 [vm] 属性作为 ViewModel 的 getter 方法。
 *    - 在 [onViewCreated] 方法中通过 [createViewModel] 方法初始化 ViewModel。
 *
 * 2. **数据观察者创建**:
 *    - 子类需要实现 [createObserver] 方法，用于创建和绑定数据观察者。
 *
 * 3. **UI 事件注册**:
 *    - 默认注册了加载等待框的显示和关闭事件，分别通过 [_viewModel.loadingChange.showDialog] 和 [_viewModel.loadingChange.dismissDialog] 实现。
 *
 * 4. **懒加载机制**:
 *    - 提供了 [isCreated] 方法，用于判断 Fragment 是否已成功初始化（即 ViewModel 是否已初始化）。
 *
 * ### 方法详解
 * - [onViewCreated]:
 *   - 调用时会初始化 ViewModel、调用父类的 [onViewCreated] 方法、创建数据观察者以及注册默认的 UI 事件。
 *
 * - [createViewModel]:
 *   - 使用 [ViewModelProvider] 获取指定类型的 ViewModel 实例，并通过 [getVmClazz] 方法动态获取 ViewModel 的 Class 对象。
 *
 * - [createObserver]:
 *   - 抽象方法，子类必须实现，用于创建与业务逻辑相关的数据观察者。
 *
 * - [isCreated]:
 *   - 判断 [vm] 属性是否已初始化，返回布尔值。
 *
 * - [registerDefUIChange]:
 *   - 注册默认的 UI 事件，包括加载等待框的显示和关闭。
 *
 * ### 使用场景
 * - 适用于基于 MVVM 架构的 Android 应用开发。
 * - 提供了统一的 ViewModel 初始化和数据绑定逻辑，减少重复代码。
 * - 支持动态加载等待框的显示和关闭，便于处理异步任务。
 */
abstract class BaseMVVMFragment<VM : BaseMVVMViewModel, VB : ViewBinding>: BaseBingFragment<VB>()  {

    //延迟初始化的viewModel变量
    private lateinit var _viewModel: VM
    //提供viewModel的getter方法
    val vm: VM get() = _viewModel

    /**
     * 当Fragment的视图被创建时调用，用于初始化viewModel、注册UI事件和创建数据观察者
     *
     * @param view 创建的视图
     * @param savedInstanceState 保存的实例状态
     */
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        //初始化viewModel
        _viewModel = createViewModel()
        //调用父类的onViewCreated方法
        super.onViewCreated(view, savedInstanceState)
        //创建数据观察者
        createObserver()
        //注册默认的UI事件
        registerDefUIChange()
    }

    /**
     * 创建viewModel
     *
     * @return 初始化后的viewModel实例
     */
    private fun createViewModel(): VM {
        //通过ViewModelProvider获取viewModel实例
        return ViewModelProvider(this)[getVmClazz(this)]
    }

    /**
     * 创建观察者
     */
    abstract fun createObserver()

    /**
     * fragment是否初始化成功
     *
     * @return 如果viewModel已初始化则返回true，否则返回false
     */
    open fun isCreated(): Boolean {
        return this::_viewModel.isInitialized
    }

    /**
     * 注册默认的UI事件
     */
    private fun registerDefUIChange() {
        //显示弹窗
        _viewModel.loadingChange.showDialog.observeForever{
            showLoading(
                it.message,
                it.cancelable,
                it.hasShadowBg,
                it.cancelTime,
                it.waitTime,
                it.useView,
                it.onCancelListener,
                it.onDismissListener
            )
        }
        //关闭弹窗
        _viewModel.loadingChange.dismissDialog.observe(getViewLifecycleOwner()) {
            dismissLoading(it)
        }
    }
}
